home *** CD-ROM | disk | FTP | other *** search
/ Practical Algorithms for Image Analysis / Practical Algorithms for Image Analysis.iso / TARFILE.GZ / tarfile / ch_3.2 / medfltr / medfltr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-09-11  |  5.4 KB  |  205 lines

  1. /* 
  2.  * medfltr.c
  3.  * 
  4.  * Practical Algorithms for Image Analysis
  5.  * 
  6.  * Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
  7.  */
  8.  
  9. /* MEDFLTR:     program performs median filtering on image
  10.  *                usage: medfltr inimg outimg [-s fltrSize] [-L]
  11.  *
  12.  */
  13.  
  14. #define SIZE_DFLT 3             /* default filter size */
  15. #define MAXLIST 225             /* max list size */
  16.  
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <images.h>
  21. #include <tiffimage.h>
  22. extern void print_sos_lic ();
  23.  
  24. unsigned char median2 ();       /* median filter function */
  25. long list[MAXLIST];             /* list of filter neighborhood */
  26. long nList;                     /* length of list */
  27.  
  28. long usage (short);
  29. long input (int, char **, long *);
  30.  
  31. main (argc, argv)
  32.      int argc;
  33.      char *argv[];
  34. {
  35.   Image *imgI, *imgO;           /* I/O image structure */
  36.   unsigned char **imgIn, **imgOut;  /* input and output images */
  37.   long width, height;           /* image size */
  38.   long fltrSize;                /* filter mask size */
  39.   long midFltr;                 /* middle filter coefficient */
  40.   long xEnd, yEnd;              /* end of image minus borders */
  41.   long xxEnd, yyEnd;
  42.   long x, y, xx, yy;
  43.  
  44.   if (input (argc, argv, &fltrSize) < 0)
  45.     return (-1);
  46.  
  47. /* allocate input and output image memory */
  48.   imgI = ImageIn (argv[1]);
  49.   imgIn = imgI->img;
  50.   height = ImageGetHeight (imgI);
  51.   width = ImageGetWidth (imgI);
  52.   printf ("Image size is %dx%d. Filter size is %d.\n",
  53.           width, height, fltrSize);
  54.  
  55.   imgO = ImageAlloc (height, width, 8);
  56.   imgOut = ImageGetPtr (imgO);
  57.  
  58. /* set border regions of output image to zero */
  59.   midFltr = (fltrSize - 1) / 2;
  60.   for (y = 0; y < height; y++)
  61.     for (x = 0; x < midFltr; x++)
  62.       imgOut[y][x] = imgOut[y][width - x - 1] = 0;
  63.   for (y = 0; y < midFltr; y++)
  64.     for (x = 0; x < width; x++)
  65.       imgOut[y][x] = imgOut[height - y - 1][x] = 0;
  66.  
  67. /* perform filtering */
  68.   yEnd = height - midFltr;
  69.   xEnd = width - midFltr;
  70.   for (y = midFltr; y < yEnd; y++) {
  71.     for (x = midFltr; x < xEnd; x++) {
  72.       yyEnd = y + midFltr;
  73.       xxEnd = x + midFltr;
  74.       for (yy = y - midFltr, nList = 0; yy <= yyEnd; yy++)
  75.         for (xx = x - midFltr; xx <= xxEnd; xx++, nList++)
  76.           list[nList] = imgIn[yy][xx];
  77.       imgOut[y][x] = median2 ();
  78.     }
  79.   }
  80.  
  81. /* write out median-filtered image */
  82.   ImageOut (argv[2], imgO);
  83.  
  84.   return (0);
  85. }
  86.  
  87.  
  88. /* MEDIAN2: function returns median value from an input list of integer values
  89.  *        This function is more efficient than function MEDIAN1 when
  90.  *          the number of points <n> is small wrt the number of values that
  91.  *          they may take on.
  92.  *              usage: med = median2()
  93.  */
  94.  
  95. unsigned char
  96. median2 ()
  97. {
  98.   long arrayle[MAXLIST],        /* array of number of values that is less
  99.                                  * * than or equal to the corresponding
  100.                                  * * <value> */
  101.     value[MAXLIST],             /* value corresponding to less than or
  102.                                  * * equal to array <arrayle> */
  103.     nd2;                        /* number of input values, divided by 2 */
  104.  
  105.   register long sumle,          /* running sum of less than or equals */
  106.     sum,                        /* sum of numbers less than or equal to */
  107.     i, j;
  108.  
  109.  
  110. /* initialize */
  111.   for (i = 0; i < nList; i++)
  112.     arrayle[i] = 0;
  113.  
  114. /* construct less than or equal to array */
  115.   for (i = 0; i < nList; i++) {
  116.     sumle = 0;
  117.     for (j = 0; j < nList; j++)
  118.       if (list[i] <= list[j])
  119.         sumle++;
  120.     arrayle[sumle]++;
  121.     value[sumle] = list[i];
  122.   }
  123.  
  124. /* find median */
  125.   nd2 = nList / 2;
  126.   sum = 0;
  127.   for (i = 1; i <= nList; i++) {
  128.     sum += arrayle[i];
  129.     if (sum > nd2)
  130.       break;
  131.   }
  132.  
  133.   return ((unsigned char) value[i]);
  134. }
  135.  
  136.  
  137.  
  138. /* USAGE:       function gives instructions on usage of program
  139.  *                    usage: usage (flag)
  140.  *              When flag is 1, the long message is given, 0 gives short.
  141.  */
  142.  
  143. long
  144. usage (flag)
  145.      short flag;                /* flag =1 for long message; =0 for short message */
  146. {
  147.  
  148. /* print short usage message or long */
  149.   printf ("USAGE: medfltr inimg outimg [-s FLTRSIZE] [-L]\n");
  150.   if (flag == 0)
  151.     return (-1);
  152.  
  153.   printf ("\nmedfltr performs median filtering upon image\n");
  154.   printf ("using filter window of chosen size.\n\n");
  155.   printf ("ARGUMENTS:\n");
  156.   printf ("    inimg: input image filename (TIF)\n");
  157.   printf ("   outimg: output image filename (TIF)\n\n");
  158.   printf ("OPTIONS:\n");
  159.   printf ("  -s FLTR_SIZE: filter size; the larger the size,\n");
  160.   printf ("                the greater the degree of smoothing;\n");
  161.   printf ("                the size must be odd. (Default = %d)\n", SIZE_DFLT);
  162.   printf ("            -L: print Software License for this module\n");
  163.   return (-1);
  164. }
  165.  
  166.  
  167. /* INPUT:       function reads input parameters
  168.  *                  usage: input (argc, argv, &fltrSize)
  169.  */
  170.  
  171. #define USAGE_EXIT(VALUE) {usage (VALUE); return (-1);}
  172.  
  173. long
  174. input (argc, argv, fltrSize)
  175.      int argc;
  176.      char *argv[];
  177.      long *fltrSize;            /* sidelength of square filter */
  178. {
  179.   long n;
  180.  
  181.   if (argc < 3)
  182.     USAGE_EXIT (1);
  183.  
  184.   *fltrSize = SIZE_DFLT;
  185.  
  186.   for (n = 3; n < argc; n++) {
  187.     if (strcmp (argv[n], "-s") == 0) {
  188.       if (++n == argc || argv[n][0] == '-')
  189.         USAGE_EXIT (0);
  190.       *fltrSize = atol (argv[n]);
  191.     }
  192.     else if (strcmp (argv[n], "-L") == 0) {
  193.       print_sos_lic ();
  194.       exit (0);
  195.     }
  196.     else
  197.       USAGE_EXIT (0);
  198.   }
  199.  
  200.   if (!(*fltrSize % 2))
  201.     *fltrSize += 1;
  202.  
  203.   return (0);
  204. }
  205.